function ModuleDialogHistory(doc, container, width, height, user, date, options) {
  this._doc = doc;
  this._container = container;
  this._width = width;
  this._height = height;
  this._user = user;
  this._date = date;
  this._options = options;
  
  this._object = (options && options.object) ? options.object : {};
  this._popupBox = (options && options.popupBox) ? options.popupBox : null;
  this._models = (options && options.models) ? options.models : [];
  this._states = (options && options.states) ? options.states : [];
  this._transitions = (options && options.transitions) ? options.transitions :[];
  
  this._createElements();
};

ModuleDialogHistory.prototype._createElements = function() {
  var  _self = this;
  this._gui = new DialogHistory(this._doc, this._container, this._width, this._height, this._user, this._date, this._options)._gui;
  
  this._loadData();
};

ModuleDialogHistory.prototype._loadData = function() {
  DOMUtils.removeTableRows(this._gui.main, 1);
  var tr, td;
  tr = this._gui.main.insertRow(-1);
  td = tr.insertCell(-1);
  td.colSpan = 4;
  td.appendChild(DOMUtils.getLoadingImage());
  
  this._events = null;
  this._tracks = null;
  this._notes = null;
  this._retrieveEvents();
  this._retrieveTracks();
  this._retrieveNotes();
};

ModuleDialogHistory.prototype._verifyData = function() {
  if (this._events && this._tracks && this._notes) {
    this._updateElements();
  }
};

ModuleDialogHistory.prototype._retrieveEvents = function() {
  var _self = this;
  var args = '&c=t.task_id=' + this._object.id;
  new RequestUtils()._mysql('pz_task_event', args, function(result, params) { _self._events = result.data;
                                                                              _self._verifyData.call(_self);
                                                                            }, null);
};

ModuleDialogHistory.prototype._retrieveTracks = function() {
  var _self = this;
  var args = '&c=t.task_id=' + this._object.id;
  new RequestUtils()._mysql('pz_task_track', args, function(result, params) { _self._tracks = result.data;
                                                                              _self._verifyData.call(_self);
                                                                            }, null);
};

ModuleDialogHistory.prototype._retrieveNotes = function() {
  var _self = this;
  var args = '&c=t.is_planning = 1 AND t.note_is_canceled = 0 AND t.task_id=' + this._object.id;
  new RequestUtils()._mysql('pz_task_note', args, function(result, params) { _self._notes = result.data;
                                                                              _self._verifyData.call(_self);
                                                                            }, null);
};

ModuleDialogHistory.prototype._updateElements = function() {
  var table, tr, td, radio, input, unique = MiscUtils.unique(), _self = this;
  DOMUtils.removeTableRows(this._gui.main, 1);
  DOMUtils.removeChildElements(this._gui.title);

  //  MiscUtils.sort(this._events, ['id']);
  MiscUtils.sort(this._tracks, ['id']);
  
  track = (this._tracks.length > 0) ? this._tracks[this._tracks.length - 1] : null;
  
  if (this._events.length == 0) {
    tr = this._gui.main.insertRow(-1);
    td = tr.insertCell(-1);
    td.colSpan = 4;
    td.style.height = '24px';
    td.style.textAlign = 'left';
    td.style.paddingLeft = '5px';
    td.appendChild(document.createTextNode('n/a'));
  }
  
  for (var i = 0, il = this._events.length; i < il; i++) {
    var item = this._events[i];
    tr = this._gui.main.insertRow(-1);
    
    td = tr.insertCell(-1);
    td.style.height = '24px';
    td.style.textAlign = 'left';
    td.style.padding = '0 5px';
    td.appendChild(document.createTextNode(SimpleDate.format(SimpleDate.fromStamp(item.date))));
    
    td = tr.insertCell(-1);
    td.style.textAlign = 'left';
    td.style.padding = '0 5px';
    td.appendChild(document.createTextNode((item.user) ? item.user : '-'));
    
    var state = PPublishUtils.object(item.state_id, this._states);
    var transition = PPublishUtils.object(item.transition_id, this._transitions);
    var str = state.name + ((transition) ? ' (' + transition.name + ')' : '');
    if (str != '') {
      td = tr.insertCell(-1);
      td.style.textAlign = 'left';
      td.style.padding = '0 5px';
      td.style.whiteSpace = 'nowrap';
      td.appendChild(document.createTextNode(str));
      td = tr.insertCell(-1);
      td.style.textAlign = 'left';
      td.style.padding = '0 5px';
      td.style.whiteSpace = 'nowrap';
      td.appendChild(document.createTextNode(item.message + ((item.message && item.overdue) ? ' / ' : '') + ((item.overdue) ? 'Overdue Reason: ' + item.overdue : '')));
    } else {
      td = tr.insertCell(-1);
      td.style.textAlign = 'left';
      td.style.padding = '0 5px';
      td.style.whiteSpace = 'nowrap';
      td.appendChild(document.createTextNode(item.message + ((item.message && item.overdue) ? ' / ' : '') + ((item.overdue) ? 'Overdue Reason: ' + item.overdue : '')));
      td = tr.insertCell(-1);
      td.style.whiteSpace = 'nowrap';
    }
  }
  
  var valid = true;
  if (this._object.is_canceled == 1 || this._object.state_id == 14 || this._object.state_id == 2) {
    valid = false;
  }
  
  if (valid && track) {
    var state = PPublishUtils.object(track.state_id, this._states);
    var transition = PPublishUtils.object(track.transition_id, this._transitions);
    var str = state.name + ((transition) ? '(' + transition.name + ')' : '');
    
    this._gui.title.appendChild(document.createTextNode(str));
    a = document.createElement('a');
    a.href = '#';
    a.style.margin = '0 0 0 5px';
    a.appendChild(document.createTextNode('Reverse'));
    a._track = track;
    a.onclick = function() { ModelUtils.reverse(_self._object, this._track, function() { _self._retrieveTracks.call(_self); _self._retrieveEvents.call(_self) }, DOMUtils.findPos(this), _self._date, _self._user, _self._notes); 
                           };
    this._gui.title.appendChild(a);
  } else {
    this._gui.title.appendChild(document.createTextNode('Reverse is not permitted, ' + ' (None)'));
  }
};